package bigoo.peer;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import bigoo.peer.BigooPeer.PropagationProtocol;
import bigoo.util.Config;
import eduni.simjava.Sim_system;

public class Simulator {

    /**
     * @param args
     * @throws IOException
     * @throws SecurityException
     */
    public static void main(String[] args) throws SecurityException, IOException {
	Sim_system.initialise();

	String protocolName = Config.getProperty(Config.PROPAGATION_PROTOCOL);
	PropagationProtocol protocol = PropagationProtocol.valueOf(protocolName);
	Map<String, BigooPeer> peersMap = new HashMap<String, BigooPeer>();
	String[] peersID = Config.getProperty(Config.PEERS).split(",");
	for (String peerID : peersID) {
	    System.out.println("Criando peer " + peerID);
	    BigooPeer peer = createPeer(peerID, protocol);

	    peersMap.put(peerID, peer);
	}
	for (String peerID : peersID) {
	    BigooPeer peer = peersMap.get(peerID);
	    String[] vizinhos = Config.getProperty(peerID).split(",");
	    for (String vizinho : vizinhos) {
		BigooPeer other = peersMap.get(vizinho);
		if (other != null) {
		    connectPeers(peer, other);
		}
	    }
	}

	Sim_system.set_trace_detail(true, true, true);
	Sim_system.set_trace_level(1);
	Sim_system.set_termination_condition(Sim_system.INTERVAL_ACCURACY, Sim_system.IND_REPLICATIONS, 0.95, 0.05, "peer1", "State");
	Sim_system.run();
    }

    public static BigooPeer createPeer(String peerID, PropagationProtocol protocol) {
	BigooPeer peer = new BigooPeer(peerID, protocol);
	new SearcherSource(peerID, Double.parseDouble(Config.getProperty(Config.TAXA_BUSCA)));
	new PublisherSource(peerID, Double.parseDouble(Config.getProperty(Config.TAXA_PUBLICA)));

	Sim_system.link_ports(peerID + "Publisher", "out", peerID, peerID + "in");
	Sim_system.link_ports(peerID + "Searcher", "out", peerID, peerID + "in");

	if (protocol == PropagationProtocol.EPIDEMIC) {
	    new EpidemicSource(peerID);
	    Sim_system.link_ports(peerID + "Epidemic", "out", peerID, peerID + "in");
	}

	return peer;
    }

    public static void connectPeers(BigooPeer peer1, BigooPeer peer2) {
	String peer1Name = peer1.getPeerID();
	String peer2Name = peer2.getPeerID();
	peer1.peerIsUp(peer2Name);
	Sim_system.link_ports(peer2Name, peer2Name + "in", peer1Name, peer1Name + peer2Name + "out");
    }

}
